home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CICA Windows Explosion!
/
The CICA Windows Explosion! - Disc 2.iso
/
winsock
/
ircii2-6.zip
/
SRC\IRCII-2.6\SOURCE\INPUT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-01-02
|
20KB
|
793 lines
/*
* input.c: does the actual input line stuff... keeps the appropriate stuff
* on the input line, handles insert/delete of characters/words... the whole
* ball o wax
*
*
* Written By Michael Sandrof
*
* Copyright(c) 1990
*
* See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT
*/
#ifndef lint
static char rcsid[] = "@(#)$Id: input.c,v 1.9 1994/07/03 08:23:47 mrg Stab $";
#endif
#include "irc.h"
#include "input.h"
#include "term.h"
#include "alias.h"
#include "vars.h"
#include "ircaux.h"
#include "window.h"
#include "screen.h"
#include "exec.h"
#define WIDTH 10
/* input_prompt: contains the current, unexpanded input prompt */
static char *input_prompt = (char *) 0;
/* input_line: the actual screen line where the input goes */
static int input_line;
/* str_start: position in buffer of first visible character in the input line */
static int str_start = 0;
/*
* upper_mark and lower_mark: marks the upper and lower positions in the
* input buffer which will cause the input display to switch to the next or
* previous bunch of text
*/
static int lower_mark;
static int upper_mark;
/* zone: the amount of editable visible text on the screen */
static int zone;
/* cursor: position of the cursor in the input line on the screen */
static int cursor = 0;
/* cursor_to_input: move the cursor to the input line, if not there already */
void
cursor_to_input()
{
Screen *old_current_screen;
old_current_screen = current_screen;
for (current_screen = screen_list; current_screen;
current_screen = current_screen->next)
{
if (current_screen->alive && is_cursor_in_display())
{
term_move_cursor(cursor, input_line);
cursor_not_in_display();
term_flush();
}
}
set_current_screen(old_current_screen);
}
/*
* update_input: does varying amount of updating on the input line depending
* upon the position of the cursor and the update flag. If the cursor has
* move toward one of the edge boundaries on the screen, update_cursor()
* flips the input line to the next (previous) line of text. The update flag
* may be:
*
* NO_UPDATE - only do the above bounds checking.
*
* UPDATE_JUST_CURSOR - do bounds checking and position cursor where is should
* be.
*
* UPDATE_FROM_CURSOR - does all of the above, and makes sure everything from
* the cursor to the right edge of the screen is current (by redrawing it).
*
* UPDATE_ALL - redraws the entire line
*/
void
update_input(update)
int update;
{
int old_start;
static int co = 0,
li = 0;
char *ptr;
int len,
free_it = 1,
cnt,
max;
char *prompt;
if (dumb)
return;
cursor_to_input();
if (current_screen->promptlist)
prompt = current_screen->promptlist->prompt;
else
prompt = input_prompt;
if (prompt)
{
if (update != NO_UPDATE)
{
char *inp_ptr = (char *) 0;
int args_used; /* this isn't used here but is
* passed to expand_alias()
*/
#ifndef _Windows
if (is_process(get_target_by_refnum(0)))
{
ptr = (char *)get_prompt_by_refnum(0);
free_it = 0;
}
else
#endif
ptr = expand_alias((char *) 0, prompt, empty_string, &args_used, NULL);
if (*ptr && ((my_strnicmp(ptr, "Password:", 9) == 0) || (my_strnicmp(ptr, "Operator Password:",18) == 0) ||
(my_strnicmp(ptr, "Server Password:", 16) == 0)))
term_echo(0);
else
term_echo(1);
len = strlen(ptr);
if (strncmp(ptr, current_screen->input_buffer, len) || !len)
{
malloc_strcpy(&inp_ptr, current_screen->input_buffer + current_screen->buffer_min_pos);
strmcpy(current_screen->input_buffer, ptr, INPUT_BUFFER_SIZE);
current_screen->buffer_pos += (len - current_screen->buffer_min_pos);
current_screen->buffer_min_pos = strlen(ptr);
strmcat(current_screen->input_buffer, inp_ptr, INPUT_BUFFER_SIZE);
new_free(&inp_ptr);
update = UPDATE_ALL;
}
if (free_it)
new_free(&ptr);
}
}
else
term_echo(1);
if ((li != LI) || (co != CO))
{
/* resized? Keep it simple and reset everything */
input_line = LI - 1;
zone = CO - (WIDTH * 2);
lower_mark = WIDTH;
upper_mark = CO - WIDTH;
cursor = current_screen->buffer_min_pos;
current_screen->buffer_pos = current_screen->buffer_min_pos;
str_start = 0;
li = LI;
co = CO;
}
old_start = str_start;
while ((current_screen->buffer_pos < lower_mark) && lower_mark > WIDTH)
{
upper_mark = lower_mark;
lower_mark -= zone;
str_start -= zone;
}
while (current_screen->buffer_pos >= upper_mark)
{
lower_mark = upper_mark;
upper_mark += zone;
str_start += zone;
}
cursor = current_screen->buffer_pos - str_start;
if ((old_start != str_start) || (update == UPDATE_ALL))
{
term_move_cursor(0, input_line);
if ((str_start == 0) && (current_screen->buffer_min_pos > 0))
{
int echo;
echo = term_echo(1);
if (current_screen->buffer_min_pos > (CO - WIDTH))
len = CO - WIDTH - 1;
else
len = current_screen->buffer_min_pos;
cnt = term_puts(&(current_screen->input_buffer[
str_start]), len);
term_echo(echo);
cnt += term_puts(&(current_screen->input_buffer[
str_start + len]), CO - len);
}
else
cnt = term_puts(&(current_screen->input_buffer[
str_start]), CO);
if (term_clear_to_eol())
term_space_erase(cnt);
term_move_cursor(cursor, input_line);
}
else if (update == UPDATE_FROM_CURSOR)
{
term_move_cursor(cursor, input_line);
cnt = cursor;
max = CO - (current_screen->buffer_pos - str_start);
if ((len = strlen(&(current_screen->input_buffer[
current_screen->buffer_pos]))) > max)
len = max;
cnt += term_puts(&(current_screen->input_buffer[
current_screen->buffer_pos]), len);
if (term_clear_to_eol())
term_space_erase(cnt);
term_move_cursor(cursor, input_line);
}
else if (update == UPDATE_JUST_CURSOR)
term_move_cursor(cursor, input_line);
term_flush();
}
void
refresh_inputline()
{
update_input(UPDATE_ALL);
}
void
change_input_prompt(direction)
int direction;
{
if (!current_screen->promptlist)
{
strcpy(current_screen->input_buffer,
current_screen->saved_input_buffer);
current_screen->buffer_pos =
current_screen->saved_buffer_pos;
current_screen->buffer_min_pos =
current_screen->saved_min_buffer_pos;
update_input(UPDATE_ALL);
}
else if (direction == -1)
{
update_input(UPDATE_ALL);
}
else if (!current_screen->promptlist->next)
{
strcpy(current_screen->saved_input_buffer,
current_screen->input_buffer);
current_screen->saved_buffer_pos =
current_screen->buffer_pos;
current_screen->saved_min_buffer_pos =
current_screen->buffer_min_pos;
*current_screen->input_buffer = '\0';
current_screen->buffer_pos =
current_screen->buffer_min_pos = 0;
update_input(UPDATE_ALL);
}
}
/* input_move_cursor: moves the cursor left or right... got it? */
void
input_move_cursor(dir)
int dir;
{
cursor_to_input();
if (dir)
{
if (current_screen->input_buffer[current_screen->buffer_pos])
{
current_screen->buffer_pos++;
if (term_cursor_right())
term_move_cursor(cursor + 1, input_line);
}
}
else
{
if (current_screen->buffer_pos > current_screen->buffer_min_pos)
{
current_screen->buffer_pos--;
if (term_cursor_left())
term_move_cursor(cursor - 1, input_line);
}
}
update_input(NO_UPDATE);
}
/*
* input_forward_word: move the input cursor forward one word in the input
* line
*/
void
input_forward_word()
{
cursor_to_input();
while (
(isspace(current_screen->input_buffer[current_screen->buffer_pos]) ||
ispunct(current_screen->input_buffer[current_screen->buffer_pos])) &&
current_screen->input_buffer[current_screen->buffer_pos])
current_screen->buffer_pos++;
while
(!(ispunct(current_screen->input_buffer[current_screen->buffer_pos]) ||
isspace(current_screen->input_buffer[current_screen->buffer_pos])) &&
current_screen->input_buffer[current_screen->buffer_pos])
current_screen->buffer_pos++;
update_input(UPDATE_JUST_CURSOR);
}
/* input_backward_word: move the cursor left on word in the input line */
void
input_backward_word()
{
cursor_to_input();
while ((current_screen->buffer_pos > current_screen->buffer_min_pos) &&
(isspace(current_screen->input_buffer[current_screen->buffer_pos - 1])
||
ispunct(current_screen->input_buffer[current_screen->buffer_pos - 1])))
current_screen->buffer_pos--;
while ((current_screen->buffer_pos > current_screen->buffer_min_pos) &&
!(ispunct(current_screen->input_buffer[current_screen->buffer_pos - 1])
||
isspace(current_screen->input_buffer[current_screen->buffer_pos - 1])))
current_screen->buffer_pos--;
update_input(UPDATE_JUST_CURSOR);
}
/* input_delete_character: deletes a character from the input line */
void
input_delete_character()
{
cursor_to_input();
if (current_screen->input_buffer[current_screen->buffer_pos])
{
char *ptr = (char *) 0;
int pos;
malloc_strcpy(&ptr,
&(current_screen->input_buffer[current_screen->buffer_pos
+ 1]));
strcpy(&(current_screen->input_buffer[
current_screen->buffer_pos]), ptr);
new_free(&ptr);
if (term_delete())
update_input(UPDATE_FROM_CURSOR);
else
{
pos = str_start + CO - 1;
if (pos < strlen(current_screen->input_buffer))
{
term_move_cursor(CO - 1, input_line);
term_putchar(current_screen->input_buffer[pos]);
term_move_cursor(cursor, input_line);
}
update_input(NO_UPDATE);
}
}
}
/* input_backspace: does a backspace in the input buffer */
/*ARGSUSED*/
void
input_backspace(key, ptr)
char *key;
void (*ptr)();
{
cursor_to_input();
if (current_screen->buffer_pos > current_screen->buffer_min_pos)
{
char *ptr = (char *) 0;
int pos;
malloc_strcpy(&ptr,
&(current_screen->input_buffer[current_screen->buffer_pos]));
strcpy(&(current_screen->input_buffer[current_screen->buffer_pos
- 1]), ptr);
new_free(&ptr);
current_screen->buffer_pos--;
if (term_cursor_left())
term_move_cursor(cursor - 1, input_line);
if (current_screen->input_buffer[current_screen->buffer_pos])
{
if (term_delete())
{
update_input(UPDATE_FROM_CURSOR);
return;
}
else
{
pos = str_start + CO - 1;
if (pos < strlen(current_screen->input_buffer))
{
term_move_cursor(CO - 1, input_line);
term_putchar(current_screen->input_buffer[pos]);
}
update_input(UPDATE_JUST_CURSOR);
}
}
else
{
term_putchar(' ');
if (term_cursor_left())
term_move_cursor(cursor - 1, input_line);
update_input(NO_UPDATE);
}
}
}
/*
* input_beginning_of_line: moves the input cursor to the first character in
* the input buffer
*/
void
input_beginning_of_line()
{
cursor_to_input();
current_screen->buffer_pos = current_screen->buffer_min_pos;
update_input(UPDATE_JUST_CURSOR);
}
/*
* input_end_of_line: moves the input cursor to the last character in the
* input buffer
*/
void
input_end_of_line()
{
cursor_to_input();
current_screen->buffer_pos = strlen(current_screen->input_buffer);
update_input(UPDATE_JUST_CURSOR);
}
/*
* input_delete_previous_word: deletes from the cursor backwards to the next
* space character.
*/
void
input_delete_previous_word()
{
int old_pos;
char c;
cursor_to_input();
old_pos = current_screen->buffer_pos;
while ((current_screen->buffer_pos > current_screen->buffer_min_pos) &&
(isspace(current_screen->input_buffer[current_screen->buffer_pos - 1])
||
ispunct(current_screen->input_buffer[current_screen->buffer_pos - 1])))
current_screen->buffer_pos--;
while ((current_screen->buffer_pos > current_screen->buffer_min_pos) &&
!(ispunct(current_screen->input_buffer[current_screen->buffer_pos - 1])
||
isspace(current_screen->input_buffer[current_screen->buffer_pos - 1])))
current_screen->buffer_pos--;
c = current_screen->input_buffer[old_pos];
current_screen->input_buffer[old_pos] = (char) 0;
malloc_strcpy(&cut_buffer,
&(current_screen->input_buffer[current_screen->buffer_pos]));
current_screen->input_buffer[old_pos] = c;
strcpy(&(current_screen->input_buffer[current_screen->buffer_pos]),
&(current_screen->input_buffer[old_pos]));
update_input(UPDATE_FROM_CURSOR);
}
/*
* input_delete_next_word: deletes from the cursor to the end of the next
* word
*/
void
input_delete_next_word()
{
int pos;
char *ptr = (char *) 0,
c;
cursor_to_input();
pos = current_screen->buffer_pos;
while ((isspace(current_screen->input_buffer[pos]) ||
ispunct(current_screen->input_buffer[pos])) &&
current_screen->input_buffer[pos])
pos++;
while (!(ispunct(current_screen->input_buffer[pos]) ||
isspace(current_screen->input_buffer[pos])) &&
current_screen->input_buffer[pos])
pos++;
c = current_screen->input_buffer[pos];
current_screen->input_buffer[pos] = (char) 0;
malloc_strcpy(&cut_buffer,
&(current_screen->input_buffer[current_screen->buffer_pos]));
current_screen->input_buffer[pos] = c;
malloc_strcpy(&ptr, &(current_screen->input_buffer[pos]));
strcpy(&(current_screen->input_buffer[current_screen->buffer_pos]), ptr);
new_free(&ptr);
update_input(UPDATE_FROM_CURSOR);
}
/*
* input_add_character: adds the character c to the input buffer, repecting
* the current overwrite/insert mode status, etc
*/
/*ARGSUSED*/
void
input_add_character(c, unused)
char c;
char *unused;
{
int display_flag = NO_UPDATE;
cursor_to_input();
if (current_screen->buffer_pos < INPUT_BUFFER_SIZE)
{
if (get_int_var(INSERT_MODE_VAR))
{
if (current_screen->input_buffer[
current_screen->buffer_pos])
{
char *ptr = (char *) 0;
malloc_strcpy(&ptr, &(
current_screen->input_buffer[
current_screen->buffer_pos]));
current_screen->input_buffer[
current_screen->buffer_pos] = c;
current_screen->input_buffer[
current_screen->buffer_pos + 1] =
(char) 0;
strmcat(current_screen->input_buffer, ptr,
INPUT_BUFFER_SIZE);
new_free(&ptr);
if (term_insert(c))
{
term_putchar(c);
if (current_screen->input_buffer[
current_screen->buffer_pos + 1])
display_flag = UPDATE_FROM_CURSOR;
else
display_flag = NO_UPDATE;
}
}
else
{
current_screen->input_buffer[
current_screen->buffer_pos] = c;
current_screen->input_buffer[
current_screen->buffer_pos + 1] =
(char) 0;
term_putchar(c);
}
}
else
{
if (current_screen->input_buffer[
current_screen->buffer_pos] == (char) 0)
current_screen->input_buffer[
current_screen->buffer_pos + 1] = (char) 0;
current_screen->input_buffer[current_screen->buffer_pos]
= c;
term_putchar(c);
}
current_screen->buffer_pos++;
update_input(display_flag);
}
}
#ifndef _Windows
/*
* set_input: sets the input buffer to the given string, discarding whatever
* was in the input buffer before
*/
void
set_input(str)
char *str;
{
strmcpy(current_screen->input_buffer + current_screen->buffer_min_pos,
str, INPUT_BUFFER_SIZE - current_screen->buffer_min_pos);
current_screen->buffer_pos = strlen(current_screen->input_buffer);
}
/*
* get_input: returns a pointer to the input buffer. Changing this will
* actually change the input buffer. This is a bad way to change the input
* buffer tho, cause no bounds checking won't be done
*/
char *
get_input()
{
return (&(current_screen->input_buffer[current_screen->buffer_min_pos]));
}
#endif
/* input_clear_to_eol: erases from the cursor to the end of the input buffer */
void
input_clear_to_eol()
{
cursor_to_input();
malloc_strcpy(&cut_buffer,
&(current_screen->input_buffer[current_screen->buffer_pos]));
current_screen->input_buffer[current_screen->buffer_pos] = (char) 0;
if (term_clear_to_eol())
{
term_space_erase(cursor);
term_move_cursor(cursor, input_line);
}
update_input(NO_UPDATE);
}
/*
* input_clear_to_bol: clears from the cursor to the beginning of the input
* buffer
*/
void
input_clear_to_bol()
{
char *ptr = (char *) 0;
cursor_to_input();
malloc_strcpy(&cut_buffer,
&(current_screen->input_buffer[current_screen->buffer_min_pos]));
cut_buffer[current_screen->buffer_pos -
current_screen->buffer_min_pos] = (char) 0;
malloc_strcpy(&ptr,
&(current_screen->input_buffer[current_screen->buffer_pos]));
current_screen->input_buffer[current_screen->buffer_min_pos] =
(char) 0;
strmcat(current_screen->input_buffer, ptr, INPUT_BUFFER_SIZE);
new_free(&ptr);
current_screen->buffer_pos = current_screen->buffer_min_pos;
term_move_cursor(current_screen->buffer_min_pos, input_line);
if (term_clear_to_eol())
{
term_space_erase(current_screen->buffer_min_pos);
term_move_cursor(current_screen->buffer_min_pos, input_line);
}
update_input(UPDATE_FROM_CURSOR);
}
/*
* input_clear_line: clears entire input line
*/
void
input_clear_line()
{
cursor_to_input();
malloc_strcpy(&cut_buffer, current_screen->input_buffer +
current_screen->buffer_min_pos);
current_screen->input_buffer[current_screen->buffer_min_pos] =
(char) 0;
current_screen->buffer_pos = current_screen->buffer_min_pos;
term_move_cursor(current_screen->buffer_min_pos, input_line);
if (term_clear_to_eol())
{
term_space_erase(current_screen->buffer_min_pos);
term_move_cursor(current_screen->buffer_min_pos, input_line);
}
update_input(NO_UPDATE);
}
/*
* input_transpose_characters: swaps the positions of the two characters
* before the cursor position
*/
void
input_transpose_characters()
{
cursor_to_input();
if (current_screen->buffer_pos > current_screen->buffer_min_pos &&
current_screen->input_buffer[current_screen->buffer_pos])
{
char c1,
c2;
c1 = current_screen->input_buffer[current_screen->buffer_pos];
c2 = current_screen->input_buffer[current_screen->buffer_pos] =
current_screen->input_buffer[current_screen->buffer_pos - 1];
current_screen->input_buffer[current_screen->buffer_pos - 1]
= c1;
if (term_cursor_left())
term_move_cursor(cursor - 1, input_line);
term_putchar(c1);
term_putchar(c2);
if (term_cursor_left())
term_move_cursor(cursor - 1, input_line);
update_input(NO_UPDATE);
}
}
/* init_input: initialized the input buffer by clearing it out */
void
init_input()
{
*current_screen->input_buffer = (char) 0;
current_screen->buffer_pos = current_screen->buffer_min_pos;
}
/*
* input_yank_cut_buffer: takes the contents of the cut buffer and inserts it
* into the input line
*/
void
input_yank_cut_buffer()
{
char *ptr = (char *) 0;
if (cut_buffer)
{
malloc_strcpy(&ptr,
&(current_screen->input_buffer[current_screen->buffer_pos]));
current_screen->input_buffer[current_screen->buffer_pos] =
(char) 0;
strmcat(current_screen->input_buffer, cut_buffer,
INPUT_BUFFER_SIZE);
strmcat(current_screen->input_buffer, ptr, INPUT_BUFFER_SIZE);
new_free(&ptr);
update_input(UPDATE_FROM_CURSOR);
current_screen->buffer_pos += strlen(cut_buffer);
if (current_screen->buffer_pos > INPUT_BUFFER_SIZE)
current_screen->buffer_pos = INPUT_BUFFER_SIZE;
update_input(UPDATE_JUST_CURSOR);
}
}
/* get_input_prompt: returns the current input_prompt */
char *
get_input_prompt()
{
return (input_prompt);
}
/*
* set_input_prompt: sets a prompt that will be displayed in the input
* buffer. This prompt cannot be backspaced over, etc. It's a prompt.
* Setting the prompt to null uses no prompt
*/
void
set_input_prompt(prompt)
char *prompt;
{
if (prompt)
{
if (input_prompt && !strcmp (prompt, input_prompt))
return;
malloc_strcpy(&input_prompt, prompt);
}
else
{
if (!input_prompt)
return;
malloc_strcpy(&input_prompt, empty_string);
}
update_input(UPDATE_ALL);
}
/*
* input_pause: prompt the user with a message then waits for a single
* keystroke before continuing. The key hit is returned.
*
* This function is NEVER to be called, once the inital irc_io()
* loop has been called from main(). Perhaps it would be better
* to just put this code at the only place it is called, and not
* have the function. If you want an input_pause, use add_wait_prompt()
* with WAIT_PROMPT_KEY.
*/
char
input_pause(msg)
char *msg;
{
char *ptr = (char *) 0;
char c;
if (dumb)
{
puts(msg);
fflush(stdout);
if (use_input)
irc_io(&c, NULL, -1, 1);
}
else
{
malloc_strcpy(&ptr, get_input());
set_input(msg);
update_input(UPDATE_ALL);
irc_io(&c, NULL, -1, 1);
set_input(ptr);
update_input(UPDATE_ALL);
new_free(&ptr);
}
return (c);
}
int term_pause(void)
{
return 0;
}